import { Component, game, v2, Vec2, _decorator } from 'cc'
import { eventDispatcher } from '../Constants';
import { EventType } from '../enums/EventType';
const { ccclass } = _decorator

@ccclass('Shake')
export class Shake extends Component {

    private _isShaking: boolean;

    private _shakeType: number;

    private _lastStamp: number

    private _originPos: Vec2 = v2();

    public onEnable(): void {
        eventDispatcher.on(EventType.SCENE_SHAKE, this.onShake, this);

    }

    public onDisable(): void {
        eventDispatcher.targetOff(this);
    }

    stop() {
        this._isShaking = false;
    }

    private onShake(type: number): void {
        if (this._isShaking) {
            return;
        }
        this._isShaking = true;
        this._shakeType = type;
        this._lastStamp = game.totalTime;
        this._originPos.set(this.node.position.x, this.node.position.y);
    }

    public update(): void {
        this.onShakeUpdate();
    }

    /***
     * 正弦震动
     * y= A * sin *(wx + f)
     */
    private onShakeUpdate(): void {
        if (!this._isShaking) {
            return;
        }

        //振幅
        const shakeAmount = 1.6;
        //持续时间
        const duration = 200;
        //频率
        const frequency = 12;
        //当前时间
        const curSecond = (game.totalTime - this._lastStamp) / 1000;
        //总时间
        const totalSecond = duration / 1000;
        const offset = shakeAmount * Math.sin(frequency * Math.PI * curSecond);

        const arr = [v2(0, -1), v2(-1, 0), v2(0, 1), v2(1, 0)];

        const pos = this._originPos.clone().add(arr[this._shakeType].clone().multiplyScalar(offset))
        this.node.setPosition(pos.x, pos.y);
        if(curSecond >= totalSecond) {
            this._isShaking = false;
            this.node.setPosition(this._originPos.x, this._originPos.y);
        }
    }
}
